﻿
using System ;
using System.Diagnostics ;
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Data ;
using System.IO ;
using System.Data.Odbc ;
using System.Windows.Forms ;


namespace MskEdit.Dbf.Backend
{
    public static class DbfProjectsIO
    {       
        #region Private static methods
        
        private static bool isMskFileIn( string rootDir, string qDir ) {
            
            DirectoryInfo projectDirectoryInfo = new DirectoryInfo( rootDir + qDir ) ;
            
            if ( ! projectDirectoryInfo.Exists )
                return false ;
                
            FileInfo[]  mskFileInfos = projectDirectoryInfo.GetFiles( "*.msk" ) ;
            
            if ( mskFileInfos.Length <= 0 ) 
                return false ;
            
            return true ;
        }
        
        
        private static DataTable reducedProjectsTableFrom( string rootDir, DataTable dbfProjectsDataTable ) {
            
            DataTable projectsDataTable = new DataTable() ;
            projectsDataTable.Columns.Add( "QDIR", typeof(string) ) ;
            projectsDataTable.Columns.Add( "PNAME_msk", typeof(string) ) ;
            
            foreach( DataRow dbfRow in dbfProjectsDataTable.Rows ) {            
                string qDir     = dbfRow["QDIR"] as string ;                    
                string pName    = dbfRow["PNAME"] as string ;
                string pNameMsk = ( isMskFileIn( rootDir, qDir ) ? "msk " : "    " ) + pName ;
                
                DataRow newRow = projectsDataTable.NewRow() ;
                newRow["QDIR"] = qDir ;
                newRow["PNAME_msk"] = pNameMsk ;
                projectsDataTable.Rows.Add( newRow ) ;
            }
            
            projectsDataTable.AcceptChanges() ;
            
            return projectsDataTable ;
        }
        
        
        private static bool validateDbfFileInfo( FileInfo dbfFileInfo, bool showMessageBoxOnFailure )
        {
            if ( ! dbfFileInfo.Extension.Equals( ".dbf", StringComparison.OrdinalIgnoreCase ) )
            {
                if ( showMessageBoxOnFailure )
                    MessageBox.Show( 
                        "Not an DBF file : '" + dbfFileInfo.FullName + "'", 
                        "CmdPrep - DBF file not found",
                        MessageBoxButtons.OK, 
                        MessageBoxIcon.Warning ) ;
                
              return false ;
            }
                           
            if ( ! dbfFileInfo.Exists )
            {
                if ( showMessageBoxOnFailure )
                    MessageBox.Show( 
                        "Unresolved file path : '" + dbfFileInfo.FullName + "'", 
                        "CmdPrep - DBF file not found",
                        MessageBoxButtons.OK, 
                        MessageBoxIcon.Warning ) ;
                
                return false ;
            }
        
            return true ;
        }
        
        private static string getConnectionString( FileInfo dbfFileInfo )
        {
            string folder     = dbfFileInfo.DirectoryName ;
            string file       = dbfFileInfo.Name ;
            string extension  = dbfFileInfo.Extension ;
                        
            return "Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=" + folder + ";" ; 
// orig    return @"Driver={Microsoft dBASE Driver ( *" + extension + " )} ;DSN=" + file + " ;DriverID=277 ;DBQ=" + folder ;
        }
        
        private static bool openOdbcConnection( OdbcConnection dbConn )
        {
            try 
            {
                if ( dbConn != null )
                    dbConn.Open() ;
            }
            catch ( System.Exception e ) 
            {                
                MessageBox.Show( 
                    "Exception caught opening DBF connection : " + e.Message, 
                    "DBF connection could not open",
                    MessageBoxButtons.OK, 
                    MessageBoxIcon.Warning ) ;
            }
            
            return ( dbConn != null ) && ( dbConn.State == ConnectionState.Open ) ;
        }
        
        
        private static DataTable tryReadDbfProjectsTable( FileInfo dbfFileInfo, DataTable fallbackTable ) { 
        
            if ( ! validateDbfFileInfo( dbfFileInfo, true /* show message box on failure */ ) )
                return fallbackTable ;
            
            string connectionString   = getConnectionString( dbfFileInfo ) ;
            if ( string.IsNullOrEmpty( connectionString ) )
                return fallbackTable ;
            
            OdbcConnection dbConn     = new OdbcConnection( connectionString ) ;
            if ( ! openOdbcConnection( dbConn ) )
                return fallbackTable ;
            
            OdbcCommand dbComm        = dbConn.CreateCommand() ;
// Orig            dbComm.CommandText = "Select PNAME, ALW, ADIR, QLW, QDIR, ZLW, ZDIR from PROJECTS where FA_NAME NOT like 'cadett%' or FA_NAME is NULL order by PNAME asc" ;
            dbComm.CommandText = "Select PNAME, ALW, ADIR, QLW, QDIR, ZLW, ZDIR from PROJECTS order by PNAME asc" ;
            
            DataTable projectsDataTable = new DataTable() ;
            
            try {
                projectsDataTable.Load( dbComm.ExecuteReader() ) ;
            }
            catch ( Exception e ) {
                System.Diagnostics.Debug.WriteLine( e.Message ) ;
            }
            
            dbConn.Close() ;
            dbComm.Dispose() ;
            dbConn.Dispose() ;
            
            Debug.Assert( projectsDataTable.Rows.Count > 0 ) ;
            
            return projectsDataTable ;
        }
                
        #endregion
        
        #region Public static methods
        
        public static DataTable tryGetProjectsTable( FileInfo dbfFileInfo, DataTable fallbackTable ) {  

            DataTable dbfProjectsTable = tryReadDbfProjectsTable( dbfFileInfo, null ) ;
            if ( dbfProjectsTable == null )
                return fallbackTable ;
                
            DataTable projectsTable = reducedProjectsTableFrom( dbfFileInfo.DirectoryName, dbfProjectsTable ) ;
            
            return projectsTable ;
        }
        
        #endregion
    }
}
